package gemini.castor.ui.client.page.content.store.catalog.productcatalog;

import gemini.basic.model.Product;
import gemini.basic.model.ProductType;
import gemini.castor.ui.client.ServiceCatalog;
import gemini.castor.ui.client.mvp.callback.AbstractAsyncCallback;
import gemini.castor.ui.client.mvp.single.CastorWidgetDisplay;
import gemini.castor.ui.client.mvp.single.CastorWidgetPresenter;
import gemini.castor.ui.client.page.RootEvent;
import gemini.castor.ui.client.page.content.store.shoppingcart.ShoppingCartEvent;
import gemini.castor.ui.client.page.content.store.shoppingcart.ShoppingCartItem;
import gemini.castor.ui.client.page.widget.dialog.GmnDialog;
import gemini.castor.ui.client.utils.GuiUtils;
import gemini.castor.ui.client.utils.PlaceConstants;

import java.util.ArrayList;
import java.util.List;

import ch.elca.gwt.mvp.client.EventBus;
import ch.elca.gwt.mvp.client.place.Place;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.inject.Inject;

public class ProductCatalogPresenter extends
		CastorWidgetPresenter<ProductCatalogPresenter.Display> {

	@Inject
	public ProductCatalogPresenter(Display display, EventBus globalEventBus) {
		super(display, globalEventBus);
	}

	public interface Display extends CastorWidgetDisplay {
		void setProductTypes(List<ProductType> productTypes);
		void setProductType(ProductType productType);
		HasClickHandlers getAddToCartClickHandlers();
		short getQuantity();
		void onChangedType(Product product);
		Product getProduct();
		void setProduct(Product product);
	}

	private ProductType productType = null;
	private List<ProductType> productTypes = null;
	private Product product = null;
	
	public static final Place PLACE = new Place(PlaceConstants.PLACE_CATALOG);

	@Override
	protected void onBind() {
		
		registerHandler(eventBus.addHandler(ProductCatalogEvent.getType(), new ProductCatalogHandler() {
			
			@Override
			public void onChangeProductType(ProductCatalogEvent catalogEvent) {
				getProductsByProductType(catalogEvent.getProductTypeCode());
			}
		}));
		
		registerHandler(display.getAddToCartClickHandlers().addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				ShoppingCartItem item = createShoppingCartItem();
				ShoppingCartEvent cartEvent = new ShoppingCartEvent(ShoppingCartEvent.ForwardType.ADD);
				cartEvent.setItems(new ArrayList<ShoppingCartItem>(1));
				cartEvent.getItems().add(item);
				eventBus.fireEvent(cartEvent);
			}
		}));
		
		eventBus.fireEvent(new RootEvent(RootEvent.ForwardType.MASK));
		ServiceCatalog.getProductTypeService().getAllCategory(
				new AbstractAsyncCallback<ArrayList<ProductType>>() {

					@Override
					public void onSuccess(ArrayList<ProductType> result) {
						eventBus.fireEvent(new RootEvent(RootEvent.ForwardType.UN_MASK));
						if (result != null) {
							productTypes = result;
							display.setProductTypes(productTypes);
							
							// receive from previous screen to set selected
							// product type in list
							
							if(product != null){
								display.setProductType(product.getProductType());
							} else {
								if(productType == null){
									productType = productTypes.get(0);
								}
								display.setProductType(productType);
							}
							
							display.loadData();
						} else {
							GuiUtils.alert("Cannot find any product type in db");
						}
					}
				});
	}
	
	private void getProductsByProductType(String productTypeCode){
		eventBus.fireEvent(new RootEvent(RootEvent.ForwardType.MASK));
		ServiceCatalog.getProductTypeByCodeService().getCategoryByCode(productTypeCode, 
				new AbstractAsyncCallback<ProductType>() {

			@Override
			public void onSuccess(ProductType result) {
				eventBus.fireEvent(new RootEvent(RootEvent.ForwardType.UN_MASK));
				if (result != null) {
					display.setProductType(result);
					
					if(product != null){
						for (Product pr : result.getProducts()) {
							if(pr.getCode().equals(product.getCode())){
								display.onChangedType(pr);
								break;
							}
						}
					} else {
						display.onChangedType(result.getProducts().get(0));
					}
					
				} else {
					GmnDialog dlgConfirm = new GmnDialog(
							"", 
							"Cannot find any product type in db", 
							"OK", "Cancel");

					dlgConfirm.info();
				}
			}
		});
	}

	protected ShoppingCartItem createShoppingCartItem() {
		ShoppingCartItem item = new ShoppingCartItem();
		item.setQuantity(display.getQuantity());
		item.setProduct(display.getProduct());
		if(item.getQuantity() < 1){
			item.setQuantity(1);
		}
		return item;
	}
	
	@Override
	public void onUnbind(){
		productType = null;
		productTypes = null;
		product = null;
	}
	
	@Override
	public void setInputObject(Object ob){
		if(ob instanceof ProductType){
			productType = (ProductType)ob;
		} else {
			// mean productCode
			product = (Product)ob;
		}
	}

	@Override
	public Place getPlace() {
		return PLACE;
	}
}
